﻿using System;
using System.Web;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using EasyClassWEBAPI.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Hosting;
using System.IO;
using System.Reflection.Metadata;
using System.Net.Http;
using System.Net;
using Renci.SshNet.Messages;
using System.Net.Http.Headers;
using EasyClassWEBAPI.Utils;
using EasyClassWEBAPI.EntityClass;
using Microsoft.EntityFrameworkCore;
using System.Runtime.CompilerServices;

namespace EasyClassWEBAPI.Controllers
{
    /// <summary>
    /// 资源存储的方法概述：
    /// 1.前端将文件以FormData的形式通过Http传送文件到后端
    /// 2.对于学习资源等文件存储到“树形结构”文件夹中，按类型索引上传下载
    /// 3.对于Post(问题/帖子,附件除外)以二进制流的形式(BLOB)存储到MySQL服务器中
    /// </summary>
    [Route("Resource")]
    [ApiController]
    public class ResourceController : ControllerBase
    {
        private EasyClassContext db;
        
        private readonly IWebHostEnvironment HostEnvironment;
        
        public ResourceController(EasyClassContext context, IWebHostEnvironment Environment)
        {
            this.db = context;
            this.HostEnvironment = Environment;
        }
        
        /// <summary>
        /// 向指定的ResourceList上传文件，使用Http的形式传递 Post:resource/upload
        /// isGroup指明是否为学习小组的资源列表，反之为帖子的附件列表。
        /// ID为StudyGroupID或PostID
        /// </summary>
        /// <param name="body"></param>
        /// <param name="isGroup"></param>
        /// <param name="ID"></param>
        /// <returns></returns>
        
        [HttpPost("Upload")]
        public async Task<IActionResult> Upload([FromForm] IFormCollection body, bool isGroup, int ID)
        {
            try
            {
                if (body.Files.Count <= 0) return NotFound("No Upload Files!");

                //利用IWebHostEnvironment(.Net Core3.0)获取当前的路径
                string ContentRootPath = HostEnvironment.ContentRootPath;
                string ResourePath = PathManager.GetPath(ContentRootPath, ID, isGroup);

                //判断是否存在相依赖的StudyGroup或Post
                StudyGroup studyGroup = null;
                Post post = null;
                if(isGroup)
                {
                    studyGroup = db.StudyGroups.Include(o=>o.StudyResources)
                        .FirstOrDefault(o => o.StudyGroupID == ID);
                }else
                {
                    post = db.Posts.Include(o=>o.StudyResources).FirstOrDefault(o => o.PostID == ID);
                }
                if (studyGroup == null && post == null)
                    return BadRequest("You must create StudyGroup or Post Before Upload files!");

                string ReturnMessge = "";

                //将文件流写进指定的文件夹
                foreach (IFormFile formFile in body.Files)
                {
                    if (formFile.Length > 0)
                    {
                        //获取文件名
                        var filePath = formFile.FileName;
                        StudyResource resource = new StudyResource { FileName = filePath, FileSize = formFile.Length };
                        if (isContainResource(studyGroup,post,resource))
                            ReturnMessge += $"{filePath} has Upoaded.\n";
                        else
                        {
                            //此文件不存在则上传，创建文件流
                            using (FileStream fs = System.IO.File.Create(ResourePath + filePath))
                            {
                                //多文件异步写入
                                await formFile.CopyToAsync(fs);
                            }
                            if(studyGroup!=null)
                            {
                                studyGroup.StudyResources.Add(resource);
                            }
                            else
                            {
                                post.StudyResources.Add(resource);
                            }
                            ReturnMessge += $"Upload {filePath} Successfully\n";
                        }
                    }
                }
                db.SaveChanges();//保存结果
                return Ok(ReturnMessge);
            }
            catch (Exception error)
            {
                return BadRequest($"Upload Failed,Reason:{error.Message}");
            }
        }
        
        /// <summary>
        /// 判断StudyGroup或Post是否包含一个StudyResource
        /// </summary>
        /// <param name="studyGroup"></param>
        /// <param name="post"></param>
        /// <param name="studyResource"></param>
        /// <returns></returns>
        private bool isContainResource(StudyGroup studyGroup,Post post,StudyResource studyResource)
        {
            if(studyGroup!=null&&studyGroup.StudyResources.Contains(studyResource))
            {
                return true;
            }
            if(post!=null&&post.StudyResources.Contains(studyResource))
            {
                return true;
            }
            return false;
        }
       
        /// <summary>
        /// 下载学习资源或者附件 Get:resource/download
        /// isGroup与ID的含义与上传文件的相同
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="isGroup"></param>
        /// <param name="ID"></param>
        /// <returns></returns>
        [HttpGet("Download")]
        public IActionResult Download(string filename, bool isGroup, int ID)
        {
            //获取文件所在的文件夹
            string ContentRootPath = HostEnvironment.ContentRootPath;
            string ResourePath = PathManager.GetPath(ContentRootPath, ID, isGroup);
            DirectoryInfo directoryInfo = new DirectoryInfo(ResourePath);
            FileInfo fileInfo = directoryInfo.GetFiles().FirstOrDefault(o => o.Name == filename);
            if (fileInfo != null)
            {
                Stream fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read);

                return File(fs, "application/octet-stream", filename);
            }
            else
            {
                //未查询到此文件
                return NotFound("This File didn't exist");
            }
        }
        
        /// <summary>
        /// 前端下载文件的函数，已经测试完成，可以直接使用
        /// </summary>
        /// <param name="Filename"></param>
        /// <param name="isGroup"></param>
        /// <param name="ID"></param>
        public static async void DownloadFile(string Filename, bool isGroup, int ID)
        {
            try
            {
                string url = @$"https://localhost:5001/resource/download?filename={Filename}&isGroup={isGroup}&ID={ID}";
                HttpClient Client = new HttpClient();
                var response = await Client.GetAsync(url);
                response.EnsureSuccessStatusCode();//确保正常运作
                var stream = await response.Content.ReadAsStreamAsync();
                //var filename = response.Content.Headers.ContentDisposition.FileName;
                using (var filestream = new FileStream(@$"E:\{Filename}", FileMode.Create, FileAccess.Write))
                {
                    stream.CopyTo(filestream);
                }
            }
            catch (Exception error)
            {
                Console.WriteLine(error.Message);
            }
        }
        
        /// <summary>
        /// 删除指定的文件 Delete:resource/delete
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="isGroup"></param>
        /// <param name="ID"></param>
        /// <returns></returns>
        [HttpDelete("Delete")]
        public IActionResult Delete(string filename, bool isGroup, int ID)
        {
            try
            {
                //判断是否存在相依赖的StudyGroup或Post
                StudyGroup studyGroup = null;
                Post post = null;
                if (isGroup)
                {
                    studyGroup = db.StudyGroups.Include(o => o.StudyResources)
                        .FirstOrDefault(o => o.StudyGroupID == ID);
                }
                else
                {
                    post = db.Posts.Include(o => o.StudyResources).FirstOrDefault(o => o.PostID == ID);
                }
                if (studyGroup == null && post == null)
                    return BadRequest("You must create StudyGroup or Post Before Upload files!");

                //判断文件是否存在
                StudyResource resource = new StudyResource { FileName = filename };
                if (!isContainResource(studyGroup, post, resource))
                    return NotFound("File didn't exist!");

                //获取文件所在的文件夹
                string ContentRootPath = HostEnvironment.ContentRootPath;
                string ResourePath = PathManager.GetPath(ContentRootPath, ID, isGroup);

                //开始删除文件
                DirectoryInfo directoryInfo = new DirectoryInfo(ResourePath);
                FileInfo fileInfo = directoryInfo.GetFiles().FirstOrDefault(o => o.Name == filename);
                if (fileInfo != null)
                {
                    System.IO.File.Delete(fileInfo.FullName);
                    StudyResource studyResource = null;
                    if(studyGroup!=null)
                    {
                        studyResource = studyGroup.StudyResources.FirstOrDefault(o => o.FileName == filename);
                    }
                    else
                    {
                        studyResource = post.StudyResources.FirstOrDefault(o => o.FileName == filename);
                    }
                    
                    db.StudyResources.Remove(studyResource);
                    db.SaveChanges();
                }

                return Ok("Delete File Successfully");
            }
            catch (Exception error)
            {
                return BadRequest($"Delete File Failed. Reson:{error.Message}");
            }
        }

    }
}
